
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  
<!-- Mirrored from werkzeug.palletsprojects.com/en/1.0.x/request_data/ by HTTrack Website Copier/3.x [XR&CO'2014], Tue, 15 Sep 2020 06:37:09 GMT -->
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Dealing with Request Data &#8212; Werkzeug Documentation (1.0.x)</title>
    <link rel="stylesheet" href="../_static/werkzeug.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" type="text/css" href="../../../../assets.readthedocs.org/static/css/badge_only.css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script async="async" type="text/javascript" src="../../../../assets.readthedocs.org/static/javascript/readthedocs-doc-embed.js"></script>
    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../genindex/index.html" />
    <link rel="search" title="Search" href="../search/index.html" />
    <link rel="next" title="Changelog" href="../changes/index.html" />
    <link rel="prev" title="Unicode" href="../unicode/index.html" />
    <link rel="canonical" href="index.html">
  <script>DOCUMENTATION_OPTIONS.URL_ROOT = '../index.html';</script>
   
  
<!-- RTD Extra Head -->

<!-- 
Always link to the latest version, as canonical.
http://docs.readthedocs.org/en/latest/canonical.html
-->
<link rel="canonical" href="index.html" />

<link rel="stylesheet" href="../../../../assets.readthedocs.org/static/css/readthedocs-doc-embed.css" type="text/css" />

<script type="text/javascript" src="../_static/readthedocs-data.js"></script>

<!-- Add page-specific data, which must exist in the page js, not global -->
<script type="text/javascript">
READTHEDOCS_DATA['page'] = "request_data"
READTHEDOCS_DATA['source_suffix'] = ".rst"
</script>

<script type="text/javascript" src="../../../../assets.readthedocs.org/static/javascript/readthedocs-analytics.js" async="async"></script>

<!-- end RTD <extrahead> -->
</head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex/index.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex/index.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../changes/index.html" title="Changelog"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="../unicode/index.html" title="Unicode"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">Werkzeug Documentation (1.0.x)</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="dealing-with-request-data">
<span id="id1"></span><h1>Dealing with Request Data<a class="headerlink" href="#dealing-with-request-data" title="Permalink to this headline">¶</a></h1>
<p>The most important rule about web development is “Do not trust the user”.
This is especially true for incoming request data on the input stream.
With WSGI this is actually a bit harder than you would expect.  Because
of that Werkzeug wraps the request stream for you to save you from the
most prominent problems with it.</p>
<div class="section" id="missing-eof-marker-on-input-stream">
<h2>Missing EOF Marker on Input Stream<a class="headerlink" href="#missing-eof-marker-on-input-stream" title="Permalink to this headline">¶</a></h2>
<p>The input stream has no end-of-file marker.  If you would call the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code> method on the <cite>wsgi.input</cite> stream you would cause your
application to hang on conforming servers.  This is actually intentional
however painful.  Werkzeug solves that problem by wrapping the input
stream in a special <code class="xref py py-class docutils literal notranslate"><span class="pre">LimitedStream</span></code>.  The input stream is exposed
on the request objects as <code class="xref py py-attr docutils literal notranslate"><span class="pre">stream</span></code>.  This one is either
an empty stream (if the form data was parsed) or a limited stream with
the contents of the input stream.</p>
</div>
<div class="section" id="when-does-werkzeug-parse">
<h2>When does Werkzeug Parse?<a class="headerlink" href="#when-does-werkzeug-parse" title="Permalink to this headline">¶</a></h2>
<p>Werkzeug parses the incoming data under the following situations:</p>
<ul class="simple">
<li>you access either <code class="xref py py-attr docutils literal notranslate"><span class="pre">form</span></code>, <code class="xref py py-attr docutils literal notranslate"><span class="pre">files</span></code>,
or <code class="xref py py-attr docutils literal notranslate"><span class="pre">stream</span></code> and the request method was
<cite>POST</cite> or <cite>PUT</cite>.</li>
<li>if you call <code class="xref py py-func docutils literal notranslate"><span class="pre">parse_form_data()</span></code>.</li>
</ul>
<p>These calls are not interchangeable.  If you invoke <code class="xref py py-func docutils literal notranslate"><span class="pre">parse_form_data()</span></code>
you must not use the request object or at least not the attributes that
trigger the parsing process.</p>
<p>This is also true if you read from the <cite>wsgi.input</cite> stream before the
parsing.</p>
<p><strong>General rule:</strong> Leave the WSGI input stream alone.  Especially in
WSGI middlewares.  Use either the parsing functions or the request
object.  Do not mix multiple WSGI utility libraries for form data
parsing or anything else that works on the input stream.</p>
</div>
<div class="section" id="how-does-it-parse">
<h2>How does it Parse?<a class="headerlink" href="#how-does-it-parse" title="Permalink to this headline">¶</a></h2>
<p>The standard Werkzeug parsing behavior handles three cases:</p>
<ul class="simple">
<li>input content type was <cite>multipart/form-data</cite>.  In this situation the
<code class="xref py py-class docutils literal notranslate"><span class="pre">stream</span></code> will be empty and
<code class="xref py py-class docutils literal notranslate"><span class="pre">form</span></code> will contain the regular <cite>POST</cite> / <cite>PUT</cite>
data, <code class="xref py py-class docutils literal notranslate"><span class="pre">files</span></code> will contain the uploaded
files as <code class="xref py py-class docutils literal notranslate"><span class="pre">FileStorage</span></code> objects.</li>
<li>input content type was <cite>application/x-www-form-urlencoded</cite>.  Then the
<code class="xref py py-class docutils literal notranslate"><span class="pre">stream</span></code> will be empty and
<code class="xref py py-class docutils literal notranslate"><span class="pre">form</span></code> will contain the regular <cite>POST</cite> / <cite>PUT</cite>
data and <code class="xref py py-class docutils literal notranslate"><span class="pre">files</span></code> will be empty.</li>
<li>the input content type was neither of them, <code class="xref py py-class docutils literal notranslate"><span class="pre">stream</span></code>
points to a <code class="xref py py-class docutils literal notranslate"><span class="pre">LimitedStream</span></code> with the input data for further
processing.</li>
</ul>
<p>Special note on the <code class="xref py py-attr docutils literal notranslate"><span class="pre">get_data</span></code> method: Calling this
loads the full request data into memory.  This is only safe to do if the
<code class="xref py py-attr docutils literal notranslate"><span class="pre">max_content_length</span></code> is set.  Also you can <em>either</em>
read the stream <em>or</em> call <code class="xref py py-meth docutils literal notranslate"><span class="pre">get_data()</span></code>.</p>
</div>
<div class="section" id="limiting-request-data">
<h2>Limiting Request Data<a class="headerlink" href="#limiting-request-data" title="Permalink to this headline">¶</a></h2>
<p>To avoid being the victim of a DDOS attack you can set the maximum
accepted content length and request field sizes.  The <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequest</span></code>
class has two attributes for that: <code class="xref py py-attr docutils literal notranslate"><span class="pre">max_content_length</span></code>
and <code class="xref py py-attr docutils literal notranslate"><span class="pre">max_form_memory_size</span></code>.</p>
<p>The first one can be used to limit the total content length.  For example
by setting it to <code class="docutils literal notranslate"><span class="pre">1024</span> <span class="pre">*</span> <span class="pre">1024</span> <span class="pre">*</span> <span class="pre">16</span></code> the request won’t accept more than
16MB of transmitted data.</p>
<p>Because certain data can’t be moved to the hard disk (regular post data)
whereas temporary files can, there is a second limit you can set.  The
<code class="xref py py-attr docutils literal notranslate"><span class="pre">max_form_memory_size</span></code> limits the size of <cite>POST</cite>
transmitted form data.  By setting it to <code class="docutils literal notranslate"><span class="pre">1024</span> <span class="pre">*</span> <span class="pre">1024</span> <span class="pre">*</span> <span class="pre">2</span></code> you can make
sure that all in memory-stored fields are not more than 2MB in size.</p>
<p>This however does <em>not</em> affect in-memory stored files if the
<cite>stream_factory</cite> used returns a in-memory file.</p>
</div>
<div class="section" id="how-to-extend-parsing">
<h2>How to extend Parsing?<a class="headerlink" href="#how-to-extend-parsing" title="Permalink to this headline">¶</a></h2>
<p>Modern web applications transmit a lot more than multipart form data or
url encoded data. To extend the capabilities, subclass <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequest</span></code>
or <code class="xref py py-class docutils literal notranslate"><span class="pre">Request</span></code> and add or extend methods.</p>
<p>There is already a mixin that provides JSON parsing:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">werkzeug.wrappers</span> <span class="k">import</span> <span class="n">Request</span>
<span class="kn">from</span> <span class="nn">werkzeug.wrappers.json</span> <span class="k">import</span> <span class="n">JSONMixin</span>

<span class="k">class</span> <span class="nc">JSONRequest</span><span class="p">(</span><span class="n">JSONMixin</span><span class="p">,</span> <span class="n">Request</span><span class="p">):</span>
    <span class="k">pass</span>
</pre></div>
</div>
<p>The basic implementation of that looks like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">werkzeug.utils</span> <span class="k">import</span> <span class="n">cached_property</span>
<span class="kn">from</span> <span class="nn">werkzeug.wrappers</span> <span class="k">import</span> <span class="n">Request</span>
<span class="kn">import</span> <span class="nn">simplejson</span> <span class="k">as</span> <span class="nn">json</span>

<span class="k">class</span> <span class="nc">JSONRequest</span><span class="p">(</span><span class="n">Request</span><span class="p">):</span>
    <span class="nd">@cached_property</span>
    <span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mimetype</span> <span class="o">==</span> <span class="s2">&quot;application/json&quot;</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
  <span id="sidebar-top"></span>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  
    
            <p class="logo"><a href="../index.html">
              <img class="logo" src="../_static/werkzeug.png" alt="Logo"/>
            </a></p>
  

  <h3>Contents</h3>
  <ul>
<li><a class="reference internal" href="#">Dealing with Request Data</a><ul>
<li><a class="reference internal" href="#missing-eof-marker-on-input-stream">Missing EOF Marker on Input Stream</a></li>
<li><a class="reference internal" href="#when-does-werkzeug-parse">When does Werkzeug Parse?</a></li>
<li><a class="reference internal" href="#how-does-it-parse">How does it Parse?</a></li>
<li><a class="reference internal" href="#limiting-request-data">Limiting Request Data</a></li>
<li><a class="reference internal" href="#how-to-extend-parsing">How to extend Parsing?</a></li>
</ul>
</li>
</ul>
<h3>Navigation</h3>
<ul>
  <li><a href="../index.html">Overview</a>
    <ul>
          <li>Previous: <a href="../unicode/index.html" title="previous chapter">Unicode</a>
          <li>Next: <a href="../changes/index.html" title="next chapter">Changelog</a>
    </ul>
  </li>
</ul>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="https://werkzeug.palletsprojects.com/en/1.0.x/search/" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
  
    <div class="footer" role="contentinfo">
        &#169; Copyright 2007 Pallets.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.
    </div>
    <script>
      if (typeof READTHEDOCS_DATA !== 'undefined') {
        if (!READTHEDOCS_DATA.features) {
          READTHEDOCS_DATA.features = {};
        }
        READTHEDOCS_DATA.features.docsearch_disabled = true;
      }
    </script>

  </body>

<!-- Mirrored from werkzeug.palletsprojects.com/en/1.0.x/request_data/ by HTTrack Website Copier/3.x [XR&CO'2014], Tue, 15 Sep 2020 06:37:09 GMT -->
</html>